# !/usr/bin/env python2
# -*- coding:utf-8 -*-
from __future__ import unicode_literals, absolute_import
import requests
import time
from requests.exceptions import BaseHTTPError
from ElevatorAdmin.settings import HOST
from manufacturer.models import AuthorityCode, StatusMsg, AlarmMsg, PlatformSession, AuthorityCodeRegisterLog
from ElevatorAdmin.settings import MANUFACTURER_DICT
import datetime
from utils.logger import get_logger
import json
from celery import shared_task


logger = get_logger("socket-server")


def get_now():
    return datetime.datetime.now().strftime("%Y%m%d%H%M%S")


def get_session():
    """ 向市局注册获得session """
    mid = MANUFACTURER_DICT.get('id')
    ac = MANUFACTURER_DICT.get('ac')
    url = HOST + 'api/platform/login.json'
    data = {
        "login": {
            "id": mid,
            "ac": ac,
            "ver": 4.0,
            "t": get_now()
        }
    }
    try:
        res = requests.post(url, json=data)
    except Exception as e:
        logger.info(e)
        return None
    if res.status_code == 200:
        res = res.json()
        if res['ret']['login'][0]['c'] == "0":
            ses = res['ret']['login'][0]['ses']
            PlatformSession.objects.create(ses=ses)
            return ses
    return None


def do_beat():
    """ 心跳 """
    url = HOST + "api/platform/beat.json"
    ses = PlatformSession.objects.filter_active().order_by("-id").first().ses
    if not ses:
        logger.info(u"register failed , check it!")
        return
    data = {
        "ses": ses,
        "t": get_now()
    }
    try:
        res = requests.post(url, json=data)
    except Exception as e:
        logger.info(e)
        return None
    if res.status_code == 200:
        res = res.json()
        print res
        if res['ret']['hbeat'][0]['c'] == "0":
            return
        elif res['ret']['hbeat'][0]['c'] == "11":
            get_session()
            print 'session has been got again'
    logger.info(u"something wrong has happened! for do_beat")


def elevator_online_numbers():
    """ 电梯在线数 """
    ses = PlatformSession.objects.filter_active().order_by("-id").first().ses
    manufacturer_code = AuthorityCode.objects.filter_active().values("manufacturer_code").distinct()
    data = {
        "ses": ses,
        "eo": []
    }
    for code in manufacturer_code:
        print code
        es = AuthorityCode.objects.filter_active(manufacturer_code=code)
        tn = es.count()
        on = es.filter(is_online=True).count()
        data['eo'].append({"f": code['manufacturer_code'], "tn": str(tn), "on": str(on), "t": get_now()})
    url = HOST + "api/platform/odev/eno.json"
    print data
    try:
        res = requests.post(url, json=data)
    except Exception as e:
        logger.info(e)
        return None
    if res.status_code == 200:
        res = res.json()
        print res
        if res['ret']['eo'][0]['c'] == '0':
            logger.info("success for elevator_online_numbers")
            return
    logger.info(u"something wrong has happened! for elevator_online_numbers")


@shared_task
def device_status(code, t1):
    """ 外设在线状态 """
    es = AuthorityCode.objects.filter_active(code=code).first()
    ses = PlatformSession.objects.filter_active().order_by("-id").first().ses
    data = {
        "ses": ses,
        "oo": [{
            "f": es.manufacturer_code,
            "e": es.elevator_code,
            "o": es.device_code,
            "t": es.device_type,
            "s": 1 if es.is_online else 0,
            "t1": t1,
            "t2": get_now()
        }]
    }
    url = HOST + "api/platform/odev/odo.json"
    try:
        res = requests.post(url, json=data)
    except Exception as e:
        logger.info(e)
        return None
    if res.status_code == 200:
        res = res.json()
        print res
        if res['ret']['oo'][0]['c'] == '0':
            logger.info("success for device_status")
            return
        elif res['ret']['oo'][0]['c'] == '12':
            # TODO 调注册接口
            return
    logger.info(u"something wrong has happened! for device_status")


def device_statistics():
    """ 外设在线率 """
    ses = PlatformSession.objects.filter_active().order_by("-id").first().ses
    data = {
        "ses": ses,
        "dr": []
    }
    manufacturer_code = AuthorityCode.objects.filter_active().values("manufacturer_code").distinct()
    device_type = AuthorityCode.objects.filter_active().values("device_type").distinct()
    for code in manufacturer_code:
        for dt in device_type:
            ac = AuthorityCode.objects.filter_active(manufacturer_code=code['manufacturer_code'], device_type=dt)
            if ac:
                num = ac.filter(is_online=True).count()
                total = ac.count()
                data['dr'].append({
                    "f": code['manufacturer_code'],
                    "t": dt['device_type'],
                    "r": "%s" % (num * 100 / total) + "%",
                    "tm": get_now()
                })
    url = HOST + "api/platform/odev/dor.json"
    try:
        res = requests.post(url, json=data)
    except Exception as e:
        logger.info(e)
        return None
    if res.status_code == 200:
        res = res.json()
        print res
        if res['ret']['dr'][0]['c'] == '0':
            logger.info("success for device_statistics")
            return
    logger.info(u"something wrong has happened! for device_statistics")


def request_tool(url, msg):
    '''
    调用市局接口工具
    :param url: 市局接口
    :param msg: 所需参数
    :return:
    '''
    headers = {'Content-Type': 'application/json'}
    try:
        res = requests.post(url, headers=headers, data=msg, timeout=10)
    except BaseHTTPError as e:
        status = False
        message = 'Error Occurred:(reason)'.format(reason=str(e.args))
        return status, message
    status = True
    data = res.json()
    return status, data


# 当提交未注册的外设的在线状态、电梯状态、电梯报警信息时，服务会返回外设未注册的错误，此时进行注册
@shared_task
def elevator_register(obj_id):
    '''
    调用电梯注册方法
    :param obj_id: 获取注册电梯信息时所需id
    :param ses: 平台在登录时从服务处获取的 ses值
    :return: res[0]:调用接口是否成功，True成功，False失败；res[1]：调用接口返回信息
    '''
    url = HOST+'api/platform/odev/eleregister.json'
    a = AuthorityCode.objects.get(id=obj_id)
    ses = PlatformSession.objects.filter_active().order_by("-id").first().ses
    data = {
        "ses": ses,
        "er": []
    }
    # TODO 使用时需补全字段
    # 字段含义
    # f  厂家编号
    # mn电梯出厂编号
    # o  外设编号
    # e 电梯注册代码，技术监督局登记注册后的20 位注册编号
    # t  外设类型，01代表采集器，02代表摄像头，03代表高清屏
    # s  在线状态：1 表示在线，0 表示不在线，其它为不合法输入
    # tm发送时间戳
    data['er'].append({'f': a.manufacturer_code_elevator, 'mn': a.manufacturer_number_elevator,
                       'o': a.device_code_elevator, 'e': a.elevator_code,
                       't': a.device_type, 's': 1 if a.is_online else 0,
                       'tm': get_now()
                       })

    send = json.dumps(data)
    try:
        res = requests.post(url, json=data)
    except Exception as e:
        logger.info(e)
        rec = u"市局服务器崩了"
        AuthorityCodeRegisterLog.objects.create(authority_code=a, send=send, rec=rec)
        return None
    if res.status_code == 200:
        res = res.json()
        rec = json.dumps(res)
        if res['ret']['er'][0]['c'] == '0':
            return
    else:
        rec = u"市局服务器崩了"
    AuthorityCodeRegisterLog.objects.create(authority_code=a, send=send, rec=rec)


@shared_task
def elevator_status(obj_id):
    '''
    电梯状态
    :param obj_ids: 获取电梯状态信息时所需信息
    :param ses: 平台在登录时从服务处获取的 ses值
    :return: res[0]:调用接口是否成功，True成功，False失败；res[1]：调用接口返回信息
    '''
    ses = PlatformSession.objects.filter_active().order_by("-id").first().ses
    data = {
        "ses": ses,
        "es": []
    }
    a = StatusMsg.objects.get(id=obj_id)
    f = a.authority_code.manufacturer_code  # 厂家编号
    e = a.authority_code.elevator_code  # 电梯注册代码
    o = a.authority_code.device_code  # 外设编号
    u = a.is_up  # 上行信号
    d = a.is_down  # 下行信号
    if a.is_stopped == 1:
        lm = 0
    elif a.is_stopped == 0 and a.is_overhauling == 0:
        lm = 1
    else:
        lm = 7
    # lm = None  # 电梯模式
    if a.is_down or a.is_up:
        rs = 1  # 运行信号
    else:
        rs = 0
    if a.is_closed == 1:
        od = 0  # 开门信号
        sd = 1  # 关门信号
    elif a.is_closed == 0:
        od = 1  # 开门信号
        sd = 0  # 关门信号
    else:
        od = 0  # 开门信号
        sd = 0  # 关门信号
    om = None  # 开门到位
    sm = None  # 关门到位
    ob = None  # 开门按钮信号
    dz = None  # 门区信号
    ol = None  # 超载信号
    fl = None  # 满载信号
    ps = a.is_there_anyone  # 电梯内是否有人
    cp = a.get_real_floor()  # 电梯所在楼层
    t = time.strftime('%Y%m%d%H%M%S')
    data['es'].append({"f": f, "e": e, "o": o, "u": u, "d":d, "lm":lm,"rs":rs,"od":od,"om":om,"sd":sd,"sm":sm,"ob":ob,"dz":dz,"ol":ol,"fl":fl,"ps":ps, "cp":cp ,"t":t})
    url = HOST+'api/platform/odev/es.json'
    try:
        res = requests.post(url, json=data)
    except Exception as e:
        logger.info(e)
        return None
    if res.status_code == 200:
        res = res.json()
        print res
        if res['ret']['es'][0]['c'] == "0":
            logger.info("success for elevator_status")
            return
    logger.info(u"something wrong has happened! for elevator_status")


@shared_task
def elevator_alarm(obj_id):
    '''
    电梯故障
    :param data: 调用电梯故障接口所需信息，
    :return: res[0]:调用接口是否成功，True成功，False失败；res[1]：调用接口返回信息
    '''
    url = HOST+'api/platform/odev/ef.json'
    ses = PlatformSession.objects.filter_active().order_by("-id").first().ses
    data = {
        "ses": ses,
        "ef": []
    }
    alarm = AlarmMsg.objects.get(id=obj_id)
    f = alarm.authority_code.manufacturer_code  # 厂家编号
    e = alarm.authority_code.elevator_code  # 电梯注册代码
    o = alarm.authority_code.device_code  # 外设编号
    s = alarm.is_alarm  # 报警状态
    if alarm.is_trapped:
        al = "2"
    elif alarm.stop_abnormal:
        al = "3"
    elif alarm.circuit_break:
        al = "4"
    elif alarm.is_top:
        al = "5"
    elif alarm.is_bottom:
        al = "6"
    elif alarm.go_with_open:
        al = "7"
    else:
        al = "0"
    er = None  # 其他故障代码
    t = alarm.create_time.strftime("%Y%m%d%H%M%S")
    data['ef'].append({"f": f, "e": e, "o": o, "s": s, "a": al, "er": er, "t": t})
    try:
        res = requests.post(url, json=data)
    except Exception as e:
        logger.info(e)
        return None
    if res.status_code == 200:
        res = res.json()
        print res
        if res['ret']['ef'][0]['c'] == "0":
            logger.info("success for elevator_alarm")
            return
    logger.info(u"something wrong has happened! for elevator_alarm")


def elevator_event(obj_id):
    """ 电梯事件 """    # TODO 什么是电梯事件？
    url = HOST + 'api/platform/odev/ef.json'
    ses = PlatformSession.objects.filter_active().order_by("-id").first().ses
    data = {
        "ses": ses,
        "es": []
    }
    a = StatusMsg.objects.get(id=obj_id)
    f = a.authority_code.manufacturer_code  # 厂家编号
    e = a.authority_code.elevator_code  # 电梯注册代码
    o = a.authority_code.device_code  # 外设编号
    pass


def elevator_statistics():
    """ 电梯统计 """
    url = HOST + 'api/platform/odev/est.json'
    ses = PlatformSession.objects.filter_active().order_by("-id").first().ses
    l = list()
    ac = AuthorityCode.objects.filter_active().exclude(id=1)
    numbers = ac.count()
    dic = {
        "ses": ses,
        "est": []
    }
    for elevator in ac:
        f = elevator.manufacturer_code
        e = elevator.elevator_code
        l.append({
            "f": f,
            "e": e,
            "t": get_now(),
            "bc": elevator.bend_times,
            "rc": elevator.run_times,
            "dc": elevator.open_times,
            "rt": elevator.up_time,
        })
    if numbers % 50 == 0:
        n = numbers / 50
    else:
        n = numbers / 50 + 1

    for i in range(n):
        dic['est'] = l[i * 50: (i + 1) * 50]
        try:
            print dic
            res = requests.post(url, json=dic)
            print res.status_code
            if res.status_code == 200:
                res = res.json()
                print res
                if res['ret']['est'][0]['c'] == "0":
                    logger.info("success for elevator_statistics")
        except Exception as e:
            logger.info(e)
    logger.info(u"something wrong has happened! for elevator_statistics")





